package com.roundarch.flex.controls.graphControlClasses
{
    import com.roundarch.flex.controls.graphControlInterfaces.IGraphControlSelector;

    import flash.events.Event;
    import flash.geom.Point;

    import mx.messaging.AbstractConsumer;

    /**
     *
     * @author Josh
     */
    public class GraphControlSelectorJoiner extends GraphControlSelector
    {
        //---------------------------------------------------------------------
        //
        //  Properties
        //
        //---------------------------------------------------------------------
        //-----------------------------
        // endOffsetForMove
        //-----------------------------
        /**
         * @private
         */
        protected var _endOffsetForMove : Number = 0;

        [Bindable("endOffsetForMoveChanged")]
        /**
         *
         *
         * @default 0
         */
        public function get endOffsetForMove() : Number
        {
            return _endOffsetForMove;
        }

        /**
         * @private
         */
        public function set endOffsetForMove(value : Number) : void
        {
            if (value == _endOffsetForMove)
            {
                return;
            }

            _endOffsetForMove = value;

            dispatchEvent(new Event("endOffsetForMoveChanged"));
        }

        //-----------------------------
        // startSelector
        //-----------------------------
        /**
         * @private
         */
        protected var _startSelector : IGraphControlSelector = null;

        [Bindable("startSelectorChanged")]
        /**
         *
         *
         * @default null
         */
        public function get startSelector() : IGraphControlSelector
        {
            return _startSelector;
        }

        /**
         * @private
         */
        public function set startSelector(value : IGraphControlSelector) : void
        {
            if (value == _startSelector)
            {
                return;
            }

            _startSelector = value;

            if (_startSelector)
            {
                _startSelector.addEventListener("valueChanged", selector_valueChanged);

                invalidateValue(_startSelector.value);
            }

            skinUpdate();

            dispatchEvent(new Event("startSelectorChanged"));
        }

        //-----------------------------
        // endSelector
        //-----------------------------
        /**
         * @private
         */
        protected var _endSelector : IGraphControlSelector = null;

        [Bindable("endSelectorChanged")]
        /**
         *
         *
         * @default null
         */
        public function get endSelector() : IGraphControlSelector
        {
            return _endSelector;
        }

        /**
         * @private
         */
        public function set endSelector(value : IGraphControlSelector) : void
        {
            if (value == _endSelector)
            {
                return;
            }

            _endSelector = value;

            if (_endSelector)
            {
                _endSelector.addEventListener("valueChanged", selector_valueChanged);
            }

            skinUpdate();

            dispatchEvent(new Event("endSelectorChanged"));
        }

        //---------------------------------------------------------------------
        //
        //  Constructor
        //
        //---------------------------------------------------------------------
        /**
         *  Constructor
         */
        public function GraphControlSelectorJoiner()
        {
            super();

            bringToFrontOnClick = false;

            alwaysVisible = true;
        }

        //---------------------------------------------------------------------
        //
        //  Methods
        //
        //---------------------------------------------------------------------
        /**
         * Requests to update the value of this control. First applies all the available constraints.
         */
        override public function invalidateValue(requested : Point = null) : void
        {
            if (!requested)
            {
                return;
            }

            super.invalidateValue(requested);

            if (endSelector && endSelector.value && startSelector && startSelector.value)
            {
                var distance : Point = new Point();

                distance.x = endSelector.value.x - startSelector.value.x;
                distance.y = endSelector.value.y - startSelector.value.y;

                if (value.x != startSelector.value.x || value.y != startSelector.value.y)
                {
                    startSelector.invalidateValue(value);
                }

                endSelector.invalidateValue(new Point(value.x + distance.x + endOffsetForMove, value.y + distance.y));
            }
        }

        //---------------------------------------------------------------------
        //
        //  Events
        //
        //---------------------------------------------------------------------
        /**
         * @private
         */
        protected function selector_valueChanged(event : Event) : void
        {
            if (startSelector && startSelector.value)
            {
                if (!value || (value.x != startSelector.value.x || value.y != startSelector.value.y))
                {
                    invalidateValue(startSelector.value);
                }
            }

            skinUpdate();
        }
    }
}
